namespace SilverSea.LPRProcessing
{
    using DTKANPRLib;
    using System;
    using System.Drawing;
    using System.Drawing.Imaging;
    using System.Runtime.InteropServices;
    using System.Threading;

    public class DTKANPRProceesing : ILPRProcessing
    {
        private ANPREngine anprengine_0;
        private bool bool_0;
        private int int_0 = 8;
        private int int_1 = 120;
        private PlateFeatures plateFeatures_0 = PlateFeatures.Both;
        private PlateNumberFixing plateNumberFixing_0;
        private string string_0 = string.Empty;
        private string string_1 = "VN";
        private string string_2 = string.Empty;

        public event ErrorEventHandler ErrorEvent;

        public bool Analyze(string fileName, ref string plateNumber)
        {
            if (this.anprengine_0 != null)
            {
                try
                {
                    IntPtr hbitmap = ((Bitmap) Image.FromFile(fileName)).GetHbitmap();
                    this.anprengine_0.ReadFromBitmap((int) hbitmap, 0);
                    DeleteObject(hbitmap);
                    if (this.anprengine_0.Plates.Count > 0)
                    {
                        Plate o = this.anprengine_0.Plates[0];//.get_Item(0);
                        for (int i = 1; i < this.anprengine_0.Plates.Count; i++)
                        {
                            Plate plate2 = this.anprengine_0.Plates[i];//.get_Item(i);
                            if (plate2.ConfidenceLevel > o.ConfidenceLevel)
                            {
                                o = plate2;
                            }
                            else
                            {
                                Marshal.ReleaseComObject(plate2);
                                plate2 = null;
                            }
                        }
                        plateNumber = o.Text;
                        if (plateNumber.Length < 6)
                        {
                            string text = string.Empty;
                            string str2 = string.Empty;
                            for (int j = 1; j < this.anprengine_0.Plates.Count; j++)
                            {
                                Plate plate3 = this.anprengine_0.Plates[j];//.get_Item(j);
                                if ((plate3.Text.Length == 3) && char.IsLetter(plate3.Text[2]))
                                {
                                    text = plate3.Text;
                                }
                                else if ((plate3.Text.Length == 4) && char.IsLetter(plate3.Text[2]))
                                {
                                    text = plate3.Text;
                                }
                                else if ((plate3.Text.Length == 4) || (plate3.Text.Length == 5))
                                {
                                    str2 = plate3.Text;
                                }
                                Marshal.ReleaseComObject(plate3);
                                plate3 = null;
                            }
                            plateNumber = text + str2;
                        }
                        if ((plateNumber.Length >= 6) && (plateNumber.Length <= 9))
                        {
                            plateNumber = this.method_1(plateNumber);
                        }
                        Marshal.ReleaseComObject(o);
                        o = null;
                    }
                }
                catch (Exception exception)
                {
                    this.CloseLPREngine();
                    Thread.Sleep(0x3e8);
                    this.CreateLPREngine();
                    if (this.ErrorEvent != null)
                    {
                        this.ErrorEvent(this, new ErrorEventArgs(exception.ToString()));
                    }
                }
                finally
                {
                    GC.Collect();
                }
            }
            return false;
        }

        public bool Analyze(string fileName, ref string[] plateNumber)
        {
            if (this.anprengine_0 != null)
            {
                try
                {
                    IntPtr hbitmap = ((Bitmap) Image.FromFile(fileName)).GetHbitmap();
                    this.anprengine_0.ReadFromBitmap((int) hbitmap, 0);
                    DeleteObject(hbitmap);
                    if (this.anprengine_0.Plates.Count > 0)
                    {
                        plateNumber = new string[this.anprengine_0.Plates.Count];
                        for (int i = 1; i < this.anprengine_0.Plates.Count; i++)
                        {
                            Plate o = this.anprengine_0.Plates[i];
                            plateNumber[i] = o.Text;
                            Marshal.ReleaseComObject(o);
                            o = null;
                        }
                    }
                }
                catch (Exception exception)
                {
                    this.CloseLPREngine();
                    Thread.Sleep(0x3e8);
                    this.CreateLPREngine();
                    if (this.ErrorEvent != null)
                    {
                        this.ErrorEvent(this, new ErrorEventArgs(exception.ToString()));
                    }
                }
                finally
                {
                    GC.Collect();
                }
            }
            return false;
        }

        public bool Analyze(string fileName, ref string[] plateNumber, ref Bitmap[] plateImage)
        {
            if (this.anprengine_0 != null)
            {
                try
                {
                    Bitmap bitmap = (Bitmap) Image.FromFile(fileName);
                    IntPtr hbitmap = bitmap.GetHbitmap();
                    this.anprengine_0.ReadFromBitmap((int) hbitmap, 0);
                    DeleteObject(hbitmap);
                    int count = this.anprengine_0.Plates.Count;
                    if (count > 0)
                    {
                        plateNumber = new string[count];
                        plateImage = new Bitmap[count];
                        for (int i = 0; i < this.anprengine_0.Plates.Count; i++)
                        {
                            Plate plate = this.anprengine_0.Plates[i];
                            plateNumber[i] = plate.Text;
                            if (plateNumber[i] != string.Empty)
                            {
                                Rectangle empty = Rectangle.Empty;
                                plateImage[i] = this.method_0(bitmap, plate, ref empty);
                            }
                            Marshal.ReleaseComObject(plate);
                            plate = null;
                        }
                    }
                }
                catch (Exception exception)
                {
                    this.CloseLPREngine();
                    Thread.Sleep(0x3e8);
                    this.CreateLPREngine();
                    if (this.ErrorEvent != null)
                    {
                        this.ErrorEvent(this, new ErrorEventArgs(exception.ToString()));
                    }
                }
                finally
                {
                    GC.Collect();
                }
            }
            return false;
        }

        public bool Analyze(string fileName, ref string plateNumber, ref Bitmap plateImage)
        {
            if (this.anprengine_0 != null)
            {
                try
                {
                    Bitmap bitmap = (Bitmap) Image.FromFile(fileName);
                    IntPtr hbitmap = bitmap.GetHbitmap();
                    this.anprengine_0.ReadFromBitmap((int) hbitmap, 0);
                    DeleteObject(hbitmap);
                    if (this.anprengine_0.Plates.Count > 0)
                    {
                        Plate plate = this.anprengine_0.Plates[0];
                        for (int i = 1; i < this.anprengine_0.Plates.Count; i++)
                        {
                            Plate o = this.anprengine_0.Plates[i];
                            if (o.ConfidenceLevel > plate.ConfidenceLevel)
                            {
                                plate = o;
                            }
                            else
                            {
                                Marshal.ReleaseComObject(o);
                                o = null;
                            }
                        }
                        plateNumber = plate.Text;
                        if (plateNumber.Length < 6)
                        {
                            string text = string.Empty;
                            string str2 = string.Empty;
                            for (int j = 1; j < this.anprengine_0.Plates.Count; j++)
                            {
                                Plate plate3 = this.anprengine_0.Plates[j];
                                if ((plate3.Text.Length == 3) && char.IsLetter(plate3.Text[2]))
                                {
                                    text = plate3.Text;
                                }
                                else if ((plate3.Text.Length == 4) && char.IsLetter(plate3.Text[2]))
                                {
                                    text = plate3.Text;
                                }
                                else if ((plate3.Text.Length == 4) || (plate3.Text.Length == 5))
                                {
                                    str2 = plate3.Text;
                                }
                                Marshal.ReleaseComObject(plate3);
                                plate3 = null;
                            }
                            plateNumber = text + str2;
                        }
                        if ((plateNumber.Length >= 6) && (plateNumber.Length <= 9))
                        {
                            plateNumber = this.method_1(plateNumber);
                        }
                        if (plateNumber != string.Empty)
                        {
                            Rectangle empty = Rectangle.Empty;
                            plateImage = this.method_0(bitmap, plate, ref empty);
                        }
                        Marshal.ReleaseComObject(plate);
                        plate = null;
                    }
                }
                catch (Exception exception)
                {
                    this.CloseLPREngine();
                    Thread.Sleep(0x3e8);
                    this.CreateLPREngine();
                    if (this.ErrorEvent != null)
                    {
                        this.ErrorEvent(this, new ErrorEventArgs(exception.ToString()));
                    }
                }
                finally
                {
                    GC.Collect();
                }
            }
            return false;
        }

        public bool Analyze(string fileName, Bitmap vehicleImage, ref string plateNumber, ref int recognizeTime, ref Bitmap plateImage)
        {
            if (this.anprengine_0 != null)
            {
                try
                {
                    IntPtr hbitmap = vehicleImage.GetHbitmap();
                    this.anprengine_0.ReadFromBitmap((int) hbitmap, 0);
                    DeleteObject(hbitmap);
                    if (this.anprengine_0.Plates.Count > 0)
                    {
                        Plate plate = this.anprengine_0.Plates[0];
                        for (int i = 1; i < this.anprengine_0.Plates.Count; i++)
                        {
                            Plate o = this.anprengine_0.Plates[i];
                            if (o.ConfidenceLevel > plate.ConfidenceLevel)
                            {
                                plate = o;
                            }
                            else
                            {
                                Marshal.ReleaseComObject(o);
                                o = null;
                            }
                        }
                        plateNumber = plate.Text;
                        if (plateNumber.Length < 6)
                        {
                            string text = string.Empty;
                            string str2 = string.Empty;
                            for (int j = 1; j < this.anprengine_0.Plates.Count; j++)
                            {
                                Plate plate3 = this.anprengine_0.Plates[j];
                                if ((plate3.Text.Length == 3) && char.IsLetter(plate3.Text[2]))
                                {
                                    text = plate3.Text;
                                }
                                else if ((plate3.Text.Length == 4) && char.IsLetter(plate3.Text[2]))
                                {
                                    text = plate3.Text;
                                }
                                else if ((plate3.Text.Length == 4) || (plate3.Text.Length == 5))
                                {
                                    str2 = plate3.Text;
                                }
                                Marshal.ReleaseComObject(plate3);
                                plate3 = null;
                            }
                            plateNumber = text + str2;
                        }
                        if ((plateNumber.Length >= 6) && (plateNumber.Length <= 9))
                        {
                            plateNumber = this.method_1(plateNumber);
                        }
                        recognizeTime = this.anprengine_0.RecognitionTime;
                        if (plateNumber != string.Empty)
                        {
                            Rectangle empty = Rectangle.Empty;
                            plateImage = this.method_0(vehicleImage, plate, ref empty);
                        }
                        Marshal.ReleaseComObject(plate);
                        plate = null;
                    }
                }
                catch (Exception exception)
                {
                    this.CloseLPREngine();
                    Thread.Sleep(0x3e8);
                    this.CreateLPREngine();
                    if (this.ErrorEvent != null)
                    {
                        this.ErrorEvent(this, new ErrorEventArgs(exception.ToString()));
                    }
                }
                finally
                {
                    GC.Collect();
                }
            }
            return false;
        }

        public bool Analyze(string fileName, Bitmap vehicleImage, ref string[] plateNumber, ref int recognizeTime, ref Bitmap[] plateImage, ref float[] confidence, ref bool[] isBlackOnWhite)
        {
            if (this.anprengine_0 != null)
            {
                try
                {
                    IntPtr hbitmap = vehicleImage.GetHbitmap();
                    this.anprengine_0.ReadFromBitmap((int) hbitmap, 0);
                    DeleteObject(hbitmap);
                    int count = this.anprengine_0.Plates.Count;
                    if (count > 0)
                    {
                        plateNumber = new string[count];
                        plateImage = new Bitmap[count];
                        confidence = new float[count];
                        for (int i = 0; i < this.anprengine_0.Plates.Count; i++)
                        {
                            Plate plate = this.anprengine_0.Plates[i];
                            plateNumber[i] = plate.Text;
                            confidence[i] = (float) plate.ConfidenceLevel;
                            if (plateNumber[i] != string.Empty)
                            {
                                Rectangle empty = Rectangle.Empty;
                                plateImage[i] = this.method_0(vehicleImage, plate, ref empty);
                            }
                            Marshal.ReleaseComObject(plate);
                            plate = null;
                        }
                        recognizeTime = this.anprengine_0.RecognitionTime;
                    }
                }
                catch (Exception exception)
                {
                    this.CloseLPREngine();
                    Thread.Sleep(0x3e8);
                    this.CreateLPREngine();
                    if (this.ErrorEvent != null)
                    {
                        this.ErrorEvent(this, new ErrorEventArgs(exception.ToString()));
                    }
                }
                finally
                {
                    GC.Collect();
                }
            }
            return false;
        }

        public bool Analyze(string fileName, Bitmap vehicleImage, ref string plateNumber, ref int recognizeTime, ref Bitmap plateImage, ref float confidence, ref bool isBlackOnWhite)
        {
            if (this.anprengine_0 != null)
            {
                try
                {
                    IntPtr hbitmap = vehicleImage.GetHbitmap();
                    this.anprengine_0.ReadFromBitmap((int) hbitmap, 0);
                    DeleteObject(hbitmap);
                    if (this.anprengine_0.Plates.Count > 0)
                    {
                        Plate plate = this.anprengine_0.Plates[0];
                        for (int i = 1; i < this.anprengine_0.Plates.Count; i++)
                        {
                            Plate o = this.anprengine_0.Plates[i];
                            if (o.ConfidenceLevel > plate.ConfidenceLevel)
                            {
                                plate = o;
                            }
                            else
                            {
                                Marshal.ReleaseComObject(o);
                                o = null;
                            }
                        }
                        plateNumber = plate.Text;
                        if (plateNumber.Length < 6)
                        {
                            string text = string.Empty;
                            string str2 = string.Empty;
                            for (int j = 1; j < this.anprengine_0.Plates.Count; j++)
                            {
                                Plate plate3 = this.anprengine_0.Plates[j];
                                if ((plate3.Text.Length == 3) && char.IsLetter(plate3.Text[2]))
                                {
                                    text = plate3.Text;
                                }
                                else if ((plate3.Text.Length == 4) && char.IsLetter(plate3.Text[2]))
                                {
                                    text = plate3.Text;
                                }
                                else if ((plate3.Text.Length == 4) || (plate3.Text.Length == 5))
                                {
                                    str2 = plate3.Text;
                                }
                                Marshal.ReleaseComObject(plate3);
                                plate3 = null;
                            }
                            plateNumber = text + str2;
                        }
                        if ((plateNumber.Length >= 6) && (plateNumber.Length <= 9))
                        {
                            plateNumber = this.method_1(plateNumber);
                        }
                        confidence = (float) plate.ConfidenceLevel;
                        recognizeTime = this.anprengine_0.RecognitionTime;
                        if (plateNumber != string.Empty)
                        {
                            Rectangle empty = Rectangle.Empty;
                            plateImage = this.method_0(vehicleImage, plate, ref empty);
                        }
                        Marshal.ReleaseComObject(plate);
                        plate = null;
                    }
                }
                catch (Exception exception)
                {
                    this.CloseLPREngine();
                    Thread.Sleep(0x3e8);
                    this.CreateLPREngine();
                    if (this.ErrorEvent != null)
                    {
                        this.ErrorEvent(this, new ErrorEventArgs(exception.ToString()));
                    }
                }
                finally
                {
                    GC.Collect();
                }
            }
            return false;
        }

        public bool Analyze(string fileName, Bitmap vehicleImage, ref string plateNumber, ref int recognizeTime, ref Bitmap plateImage, string overlayText, int overlayFontSize, Color overlayColor)
        {
            if (this.anprengine_0 != null)
            {
                try
                {
                    IntPtr hbitmap = vehicleImage.GetHbitmap();
                    this.anprengine_0.ReadFromBitmap((int) hbitmap, 0);
                    DeleteObject(hbitmap);
                    if (this.anprengine_0.Plates.Count > 0)
                    {
                        Plate plate = this.anprengine_0.Plates[0];
                        for (int i = 1; i < this.anprengine_0.Plates.Count; i++)
                        {
                            Plate o = this.anprengine_0.Plates[i];
                            if (o.ConfidenceLevel > plate.ConfidenceLevel)
                            {
                                plate = o;
                            }
                            else
                            {
                                Marshal.ReleaseComObject(o);
                                o = null;
                            }
                        }
                        plateNumber = plate.Text;
                        if (plateNumber.Length < 6)
                        {
                            string text = string.Empty;
                            string str2 = string.Empty;
                            for (int j = 1; j < this.anprengine_0.Plates.Count; j++)
                            {
                                Plate plate3 = this.anprengine_0.Plates[j];
                                if ((plate3.Text.Length == 3) && char.IsLetter(plate3.Text[2]))
                                {
                                    text = plate3.Text;
                                }
                                else if ((plate3.Text.Length == 4) && char.IsLetter(plate3.Text[2]))
                                {
                                    text = plate3.Text;
                                }
                                else if ((plate3.Text.Length == 4) || (plate3.Text.Length == 5))
                                {
                                    str2 = plate3.Text;
                                }
                                Marshal.ReleaseComObject(plate3);
                                plate3 = null;
                            }
                            plateNumber = text + str2;
                        }
                        if ((plateNumber.Length >= 6) && (plateNumber.Length <= 9))
                        {
                            plateNumber = this.method_1(plateNumber);
                        }
                        recognizeTime = this.anprengine_0.RecognitionTime;
                        if (plateNumber != string.Empty)
                        {
                            Rectangle empty = Rectangle.Empty;
                            plateImage = this.method_0(vehicleImage, plate, ref empty);
                        }
                        if (overlayText != string.Empty)
                        {
                            Graphics graphics = Graphics.FromImage(vehicleImage);
                            Brush brush = new SolidBrush(overlayColor);
                            Font font = new Font("Microsoft Sans Serif", (float) overlayFontSize);
                            if ((plate.top < (vehicleImage.Width / 2)) && ((plate.right - plate.left) != 0))
                            {
                                graphics.DrawString(DateTime.Now.ToString(), font, brush, new PointF(0f, (float) ((vehicleImage.Height - overlayFontSize) - 10)));
                            }
                            else
                            {
                                graphics.DrawString(DateTime.Now.ToString(), font, brush, new PointF(0f, 0f));
                            }
                            vehicleImage.Save(fileName, ImageFormat.Jpeg);
                            brush.Dispose();
                            graphics.Dispose();
                        }
                        Marshal.ReleaseComObject(plate);
                        plate = null;
                    }
                }
                catch (Exception exception)
                {
                    this.CloseLPREngine();
                    Thread.Sleep(0x3e8);
                    this.CreateLPREngine();
                    if (this.ErrorEvent != null)
                    {
                        this.ErrorEvent(this, new ErrorEventArgs(exception.ToString()));
                    }
                }
                finally
                {
                    GC.Collect();
                }
            }
            return false;
        }

        public void CloseLPREngine()
        {
            DestroyANPREngine(this.anprengine_0);
        }

        [DllImport("DTKANPR.dll", CharSet=CharSet.Unicode)]
        private static extern int CreateANPREngine(ref ANPREngine anprengine_1);
        public void CreateLPREngine()
        {
            if (CreateANPREngine(ref this.anprengine_0) != 0)
            {
                if (this.ErrorEvent != null)
                {
                    this.ErrorEvent(this, new ErrorEventArgs("Unable to create ANPR engine"));
                }
            }
            else
            {
                try
                {
                    this.anprengine_0.Init(false);
                }
                catch (COMException exception)
                {
                    if (this.ErrorEvent != null)
                    {
                        this.ErrorEvent(this, new ErrorEventArgs(exception.ToString()));
                    }
                }
                this.anprengine_0.LicenseManager.AddLicenseKey(this.string_0);
                this.anprengine_0.SetCountryCode(this.string_1);
                this.anprengine_0.MinCharHeight = this.int_0;
                this.anprengine_0.MaxCharHeight = this.int_1;
                this.plateNumberFixing_0 = new PlateNumberFixing();
                this.plateNumberFixing_0.CountryCode = this.string_1;
                this.plateNumberFixing_0.ProvinceCode = this.string_2;
                this.plateNumberFixing_0.PlateFeature = this.plateFeatures_0;
                this.plateNumberFixing_0.EnableMotorUnder50cc = this.bool_0;
            }
        }

        [DllImport("gdi32.dll")]
        public static extern bool DeleteObject(IntPtr hObject);
        [DllImport("DTKANPR.dll", CharSet=CharSet.Unicode)]
        private static extern int DestroyANPREngine(ANPREngine anprengine_1);
        private Bitmap method_0(Bitmap bitmap_0, Plate plate_0, ref Rectangle rectangle_0)
        {
            Bitmap bitmap = null;
            Rectangle rectangle = new Rectangle(plate_0.left, plate_0.top, plate_0.right - plate_0.left, plate_0.bottom - plate_0.top);
            int x = rectangle.X - (rectangle.Width / 5);
            int y = rectangle.Y - (rectangle.Height / 4);
            int height = rectangle.Height + ((2 * rectangle.Height) / 4);
            int width = rectangle.Width + ((2 * rectangle.Width) / 5);
            if (((plate_0.Text.Length == 4) || (plate_0.Text.Length == 5)) && ((width / height) > 1.3))
            {
                y -= (5 * width) / 4;
                height += (5 * width) / 4;
            }
            if (x < 0)
            {
                x = 0;
            }
            if (y < 0)
            {
                y = 0;
            }
            if ((x + width) > bitmap_0.Width)
            {
                width = bitmap_0.Width - x;
            }
            if ((y + height) > bitmap_0.Height)
            {
                height = bitmap_0.Height - y;
            }
            if (((x >= 0) && (y >= 0)) && ((width >= 0) && (height >= 0)))
            {
                rectangle_0 = new Rectangle(x, y, width, height);
                bitmap = Untils.CropImage(bitmap_0, rectangle_0);
            }
            return bitmap;
        }

        private string method_1(string string_3)
        {
            if (string_3.Length == 6)
            {
                if (char.IsLetter(string_3[2]) && char.IsLetter(string_3[3]))
                {
                    string_3 = string_3.Substring(0, 2) + "-" + string_3.Substring(2, 2) + "-" + string_3.Substring(4);
                }
                return string_3;
            }
            if (this.plateFeatures_0 != PlateFeatures.Both)
            {
                if (char.IsLetter(string_3[2]) && char.IsLetter(string_3[3]))
                {
                    string_3 = string_3.Substring(0, 4) + "-" + string_3.Substring(4);
                }
                else if (char.IsLetter(string_3[2]))
                {
                    if (string_3.Length == 7)
                    {
                        string_3 = string_3.Substring(0, 3) + "-" + string_3.Substring(3);
                    }
                    else if (string_3.Length == 9)
                    {
                        string_3 = string_3.Substring(0, 2) + "-" + string_3.Substring(2, 2) + "-" + string_3.Substring(4);
                    }
                    else if (this.plateFeatures_0 == PlateFeatures.MotoOnly)
                    {
                        string_3 = string_3.Substring(0, 2) + "-" + string_3.Substring(2, 2) + "-" + string_3.Substring(4);
                    }
                    else if (this.plateFeatures_0 == PlateFeatures.CarOnly)
                    {
                        string_3 = string_3.Substring(0, 3) + "-" + string_3.Substring(3);
                    }
                }
                if (string_3.Contains("-"))
                {
                    string_3 = this.plateNumberFixing_0.Fix(string_3);
                }
                return string_3;
            }
            char ch = string_3[2];
            if (ch.ToString() == "8")
            {
                string_3 = string_3.Substring(0, 2) + "B" + string_3.Substring(3);
                return string_3;
            }
            char ch2 = string_3[3];
            if (ch2.ToString() == "Z")
            {
                string_3 = string_3.Remove(3, 1).Insert(3, "2");
                return string_3;
            }
            char ch3 = string_3[3];
            if (ch3.ToString() == "S")
            {
                string_3 = string_3.Remove(3, 1).Insert(3, "5");
            }
            return string_3;
        }

        public string CountryCode
        {
            get
            {
                return this.string_1;
            }
            set
            {
                this.string_1 = value;
            }
        }

        public bool EnableMotorUnder50cc
        {
            get
            {
                return this.bool_0;
            }
            set
            {
                this.bool_0 = value;
            }
        }

        public string LPREngineProductKey
        {
            get
            {
                return this.string_0;
            }
            set
            {
                this.string_0 = value;
            }
        }

        public int MaxCharHeight
        {
            get
            {
                return this.int_1;
            }
            set
            {
                this.int_1 = value;
            }
        }

        public int MinCharHeight
        {
            get
            {
                return this.int_0;
            }
            set
            {
                this.int_0 = value;
            }
        }

        public PlateFeatures PlateFeature
        {
            get
            {
                return this.plateFeatures_0;
            }
            set
            {
                this.plateFeatures_0 = value;
            }
        }

        public string ProvinceCode
        {
            get
            {
                return this.string_2;
            }
            set
            {
                this.string_2 = value;
            }
        }
    }
}

